// Bodovi za file su minimum od bodova za dijeljenje
//
// Checker to be used by evaluator.
//
// Usage: [checker] [input] [official_output] [contestant_output]
//
// Score (real between 0.0 and 1.0) written on stdout.
// Textual description of the result written on stderr.

#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <map>

using namespace std;

typedef pair<char, int> P;

const string WRONG_OUTPUT_FORMAT = "Krivo formatiran izlaz.";
const string TEST_DATA_ERROR = "Greska u sluzbenom ulazu ili izlazu.";
const string WRONG = "Netocno.";
const string CORRECT = "Tocno.";
const string PARTIAL = "Djelomicno tocno.";

// official input
int n_cases;
int n_cards;
P first_card;
vector<P> cards;

// official output
int off_best;

// contestants data
int out_best;
vector<P> solution;

void finish(double p, const string& m) {
  cout << p << endl;
  cerr << m << endl;
  exit(0);
}

int is_card(string s) {
  return (int)s.size() == 2 && isupper(s[0]) && s[0] >= 'A' && s[0] <= 'D' && isdigit(s[1]);
}

P to_card(string s) {
  char color;
  int rank;
  sscanf(s.c_str(), "%c%d", &color, &rank);
  return P(color, rank);
}

double check_solution() {
  if (out_best != off_best)
    return 0;
  if (out_best == 0)
    return 1;
  if (first_card.first != solution[0].first &&
      first_card.second != solution[0].second)
    return 0;
  int color_change = first_card.first != solution[0].first;
  for (int i=0; i<out_best-1; i++) {
    if (solution[i].first != solution[i+1].first &&
        solution[i].second != solution[i+1].second)
      return 0;
    int new_color_change = solution[i].first != solution[i+1].first;
    if (new_color_change && color_change)
      return 0;
    color_change = new_color_change;
  }
  map<P, int> counts;
  for (auto c : cards)
    counts[c]++;
  for (auto c : solution)
    if (counts[c] == 0)
      return 0;
    else
      counts[c]--;
  return 1;
}

int main(int argc, char *argv[])
{
  assert(argc == 4);

  ifstream fin(argv[1]);
  ifstream foff(argv[2]);
  ifstream fout(argv[3]);

  assert(!fin.fail() && !fout.fail());
  
  // Read official input
  if (!(fin >> n_cases)) {
    finish(0, TEST_DATA_ERROR);
  }

  // For each case
  double min_score = 1;
  for (int z=0; z<n_cases; z++) {

    // Read official input
    string first;
    if (!(fin >> first)) {
      finish(0, TEST_DATA_ERROR);
    }
    if (!is_card(first)) {
      finish(0, TEST_DATA_ERROR);
    }
    first_card = to_card(first);  
    if (!(fin >> n_cards)) {
      finish(0, TEST_DATA_ERROR);
    }    
    string line;
    if (!(getline(fin, line))) {
      finish(0, TEST_DATA_ERROR);
    }
    istringstream in(line);
    string card;
    cards.clear();
    while (in >> card) {
      if (!is_card(card)) {
        finish(0, TEST_DATA_ERROR);
      }
      cards.push_back(to_card(card));
    }
    if ((int)cards.size() != n_cards) {
      finish(0, TEST_DATA_ERROR);
    }
    
    // Read official output
    if (!(foff >> off_best)) {
      finish(0, TEST_DATA_ERROR);
    }
    // Skip the rest in official output
    getline(foff, line);
    line = "";

    // Read contestant output
    if (!(fout >> out_best)) {
      finish(0, WRONG_OUTPUT_FORMAT);      
    } 

    solution.clear();
    if (!(getline(fout, line))) {
      finish(0, WRONG_OUTPUT_FORMAT);
    }
    istringstream contestant_in(line);
    while (contestant_in >> card) {
      if (!is_card(card)) {
        finish(0, WRONG_OUTPUT_FORMAT);
      }
      solution.push_back(to_card(card));
    }

    if ((int)solution.size() != out_best) {
      finish(0, WRONG_OUTPUT_FORMAT);
    }
    
    // Check solution
    min_score = min(min_score, check_solution());
  }

  if (min_score == 0) {
    finish(0, WRONG);
  }
  
  if (min_score < 1) {
    finish(min_score, PARTIAL);
  }

  finish(1, CORRECT);
  return 0;
}
